package com.css.project.oa.cash.service.impl;

import com.alibaba.fastjson.JSON;
import com.css.common.utils.Arith;
import com.css.common.utils.ConvertNumberToUpperUtils;
import com.css.common.utils.SecurityUtils;
import com.css.common.utils.StringUtils;
import com.css.common.utils.json.JsonUtils;
import com.css.framework.aspectj.lang.annotation.DataScope;
import com.css.framework.security.LoginUser;
import com.css.project.oa.cash.domain.ProCash;
import com.css.project.oa.cash.domain.ProCashItem;
import com.css.project.oa.cash.mapper.ProCashItemMapper;
import com.css.project.oa.cash.mapper.ProCashMapper;
import com.css.project.oa.cash.service.IProCashService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import com.css.project.oa.fileInfo.domain.SysFileInfo;
import com.css.project.oa.fileInfo.mapper.SysFileInfoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Service
public class ProCashServiceImpl implements IProCashService {

    @Autowired
    public ProCashMapper proCashMapper;

    @Autowired
    public ProCashItemMapper proCashItemMapper;

    @Autowired
    private IdentityService identityService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    public SysFileInfoMapper sysFileInfoMapper;


    @Override
    @DataScope(deptAlias = "d",userAlias="u" )
    public List<ProCash> getCashList(ProCash proCash) {
        List<ProCash> list = proCashMapper.getCashList(proCash);
        for(ProCash model : list){
            if(StringUtils.isNotEmpty(model.getInstanceId())){
                List<Task> taskList = taskService.createTaskQuery()
                        .processInstanceId(model.getInstanceId())
                        .list();    // 万一有多个
                if (!CollectionUtils.isEmpty(taskList)) {
                    Task task = taskList.get(0);
                    model.setTaskId(task.getId());
                    model.setTaskName(task.getName());
                } else {
                    model.setTaskName("已办结");
                }
            }else{
                model.setTaskName("未上报");
            }
        }
        return list ;
    }

    @Override
    public ProCash selectProCashPrintInfoById(Long id) {
        ProCash cash = proCashMapper.getPrintCashInfo(id);
        if(cash != null){
            cash.setExpenseMoneyDxPrint(ConvertNumberToUpperUtils.digitCapital(cash.getTotalAmount()));
        }else{
            cash = new ProCash();
        }
        return cash;
    }

    @Override
    public List<ProCashItem> getProCashItemList(Long cashId) {
        return proCashItemMapper.getProCashItemList(cashId);
    }

    @Override
    public List<ProCashItem> getProCashItemMainList(Long cashId) {
        return proCashItemMapper.getProCashItemMainList(cashId);
    }

    @Override
    public int reportCashByIds(Long[] ids) {
        LoginUser cu = SecurityUtils.getLoginUser() ;

        for(Long id:ids){
            Map<String, Object> mapParam = new HashMap<String, Object>();//设置查询条件
            ProCash cash1 = proCashMapper.selectProCashById(id);
            mapParam.put("cashTimeStart",cash1.getCashTimeStart()) ;
            mapParam.put("cashTimeEnd",cash1.getCashTimeEnd()) ;
            mapParam.put("expenseName",cu.getUser().getNickName()) ;
            mapParam.put("totalAmount",cash1.getTotalAmount()) ;
            mapParam.put("applyUserId",cu.getUser().getUserId()) ;
            // 用来设置启动流程的人员ID，引擎会自动把用户ID保存到activiti:initiator中
            identityService.setAuthenticatedUserId(cu.getUser().getUserId().toString());
            ProcessInstance processInstance = runtimeService // 启动流程时设置业务 key
                    .startProcessInstanceByKey("costSubmitProcess", id.toString(),mapParam);
            //完成任务
            List<Task> todoList = taskService.createTaskQuery().processDefinitionKey("costSubmitProcess").processInstanceId(processInstance.getId()).taskAssignee(cu.getUser().getUserId().toString())
                    .taskDefinitionKey("reportCash")
                    .list();
            if(todoList != null && todoList.size() > 0){
                Map<String, Object> mapParam1 = new HashMap<String, Object>();//设置查询条件
                mapParam1.put("applyUserId",cu.getUser().getUserId()) ;
                taskService.setVariablesLocal(todoList.get(0).getId(), mapParam1);//变量表里把taskId塞进去，不加的话taskId是空
                taskService.complete(todoList.get(0).getId(),mapParam1);//上报
            }

            String processInstanceId = processInstance.getId();
            ProCash cash = new ProCash() ;
            cash.setId(id);
            cash.setInstanceId(processInstanceId);
            cash.setInstanceStartTime(new Date()) ;
            cash.setUpdateTime(new Date());
            cash.setUpdateBy(cu.getUser().getUserId().toString());
            proCashMapper.updateProCash(cash) ;
        }
        return 1;
    }

    @Override
    public int reportCashAgainByIds(Long[] ids) {
        LoginUser cu = SecurityUtils.getLoginUser() ;

        for(Long id:ids){
            ProCash cash1 = proCashMapper.selectProCashById(id);
            Task task = taskService.createTaskQuery().processDefinitionKey("costSubmitProcess").processInstanceId(cash1.getInstanceId()).taskAssignee(cu.getUser().getUserId().toString())
                    .taskDefinitionKey("modifyApply")
                    .singleResult();
            Map<String, Object> mapParam1 = new HashMap<String, Object>();//设置查询条件
            mapParam1.put("applyUserId",cu.getUser().getUserId()) ;
            mapParam1.put("reApply",true) ;
            taskService.setVariablesLocal(task.getId(), mapParam1);//变量表里把taskId塞进去，不加的话taskId是空
            taskService.complete(task.getId(),mapParam1);//上报
            ProCash cash = new ProCash() ;
            cash.setId(id);
            cash.setUpdateTime(new Date());
            cash.setUpdateBy(cu.getUser().getUserId().toString());
            proCashMapper.updateProCash(cash) ;
        }
        return 1;
    }

    @Override
    @Transactional
    public Long addUpdateCash(ProCash proCash, String itemsJson) {
        LoginUser cu = SecurityUtils.getLoginUser();
        if (proCash.getId() != null) {
            proCash.setUpdateTime(new Date());
            proCash.setUpdateBy(cu.getUsername());
            proCashMapper.updateProCash(proCash);
            proCashItemMapper.removeItemByCash(proCash.getId());
        } else {
            proCash.setCreateTime(new Date());
            proCash.setCreateBy(cu.getUsername());
            proCash.setUpdateTime(new Date());
            proCash.setUpdateBy(cu.getUsername());
            proCash.setDelFlag("0");
            proCash.setBelongId(cu.getUser().getUserId());
            proCashMapper.insertProCash(proCash);
        }

        List<ProCashItem> itemList = JSON.parseArray(itemsJson, ProCashItem.class);
        Double moneySum = 0D;
        for (ProCashItem proCashItem : itemList) {
            proCashItem.setCashId(proCash.getId());
            moneySum = Arith.add(moneySum, proCashItem.getExpenseMoney());
            proCashItemMapper.insertProCashItem(proCashItem);
            String fileListStr = proCashItem.getFileList();
            if(StringUtils.isEmpty(fileListStr)) {
                continue;
            }
            List<Map> fileMapList =  JSON.parseArray(fileListStr, Map.class);
            for(Map<String, Object> map : fileMapList){
                SysFileInfo fileInfo = new SysFileInfo();
                fileInfo.setName(map.get("name").toString());
                fileInfo.setFilePath(map.get("fileName").toString());
                fileInfo.setFileSize(map.get("size").toString());
                fileInfo.setInfoTable("pro_cash_item");
                fileInfo.setInfoId(proCashItem.getId());
                fileInfo.setUploadUser(cu.getUsername());
                fileInfo.setUploadTime(new Date());
                sysFileInfoMapper.insertSysFileInfo(fileInfo);
            }

        }

        //更新报销单的总金额
        proCash.setTotalAmount(moneySum);
        proCashMapper.updateProCash(proCash);
        return proCash.getId();
    }

    @Override
    @Transactional
    public Long addUpdateCashYD(ProCash proCash) {
        LoginUser cu = SecurityUtils.getLoginUser();
        if (proCash.getId() != null) {
            proCash.setUpdateTime(new Date());
            proCash.setUpdateBy(cu.getUsername());
            proCashMapper.updateProCash(proCash);
            //proCashItemMapper.removeItemByCash(proCash.getId());
        } else {
            proCash.setCreateTime(new Date());
            proCash.setCreateBy(cu.getUsername());
            proCash.setUpdateTime(new Date());
            proCash.setUpdateBy(cu.getUsername());
            proCash.setDelFlag("0");
            proCash.setBelongId(cu.getUser().getUserId());
            proCashMapper.insertProCash(proCash);
        }
        return proCash.getId();
    }

    @Override
    public Map<String, Object> getCashById(Long cashId) {
        Map<String, Object> map = new HashMap<String, Object>();
        ProCash proCash = proCashMapper.getCashById(cashId);
        List<ProCashItem> proCashItems  = proCashItemMapper.getItemByCash(cashId);
        for(ProCashItem proCashItem :proCashItems){
            SysFileInfo info = new SysFileInfo();
            info.setInfoTable("pro_cash_item");
            info.setInfoId(proCashItem.getId());
            List<SysFileInfo> list =  sysFileInfoMapper.selectSysFileInfoList(info);
            proCashItem.setFileInfoList(list);
            proCashItem.setFileList(JsonUtils.obj2String(list));
        }
        map.put("proCash", proCash);
        map.put("proCashItems", proCashItems);
        return map;
    }

    @Override
    public int deleteCash(Long[] cashIds) {
        return proCashMapper.deleteCash(cashIds);
    }

    @Override
    public List<SysFileInfo> getFileInfoByCash(Long cashId) {
        List<SysFileInfo> list = new ArrayList<SysFileInfo>();
        List<ProCashItem> proCashItems  = proCashItemMapper.getItemByCash(cashId);
        for(ProCashItem proCashItem :proCashItems){
            SysFileInfo info = new SysFileInfo();
            info.setInfoTable("pro_cash_item");
            info.setInfoId(proCashItem.getId());
            list.addAll(sysFileInfoMapper.selectSysFileInfoList(info));
        }
        return list;
    }
    @Override
    public List<SysFileInfo> getFileInfoByCashAndFileType(Long cashId,String fileType) {
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("cashId",cashId);
        map.put("fileType",fileType);
        return sysFileInfoMapper.getFileByCashId(map);
    }

	@Override
	public int updateProCashItemForDinner(ProCashItem proCashItem) {
		// TODO Auto-generated method stub
		return proCashItemMapper.updateProCashItemForDinner(proCashItem);
	}
    
}
